package com.kg.elysia;

import com.kg.elysia.controller.AiController;
import com.kg.elysia.controller.ExcelController;
import com.kg.elysia.controller.MuralController;
import com.kg.elysia.controller.Neo4jController;
import com.kg.elysia.db.DatabaseVerticle;
import com.kg.elysia.service.MuralService;
import com.kg.elysia.service.Neo4jService;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Promise;
import io.vertx.core.http.HttpMethod;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.handler.BodyHandler;
import io.vertx.ext.web.handler.CorsHandler;
import io.vertx.ext.web.handler.StaticHandler;
import lombok.extern.slf4j.Slf4j;


@Slf4j
public class MainVerticle extends AbstractVerticle {

    private static final Integer PORT = 6688;

    @Override
    public void start(Promise<Void> startPromise) throws Exception {
        // 初始化数据库
        DatabaseVerticle dbVerticle = new DatabaseVerticle();
        vertx.deployVerticle(dbVerticle)
                .compose(res -> {
                    // 创建服务层和控制器
                    MuralService service = new MuralService(dbVerticle);
                    MuralController controller = new MuralController(service);
                    ExcelController excelController = new ExcelController(vertx, service);
                    Neo4jController neo4jController = new Neo4jController(vertx);
                    AiController aiController = new AiController(vertx, service);


                    // 配置路由
                    Router router = Router.router(vertx);
                    // 添加CORS处理程序
                    router.route().handler(CorsHandler.create()
                            .addOrigin("http://localhost:8080")
                            .addOrigin("http://127.0.0.1:8080")
                            .allowedMethod(HttpMethod.GET)
                            .allowedMethod(HttpMethod.POST)
                            .allowedHeader("Content-Type")
                            .allowedHeader("Authorization")
                            .allowCredentials(true));
                    router.route().handler(BodyHandler.create());

                    router.get("/api/murals").handler(controller::getAll);
                    router.post("/api/murals").handler(controller::create);
                    router.post("/api/murals/batch").handler(controller::batchSave);

                    router.post("/api/upload").handler(BodyHandler.create().setUploadsDirectory("uploads"));
                    router.post("/api/upload").handler(excelController::handleUpload);

                    router.get("/api/graph").handler(neo4jController::getFullGraph);

                    router.post("/api/ask").handler(aiController::ask);

                    // 静态文件服务 - Vue打包文件
                    StaticHandler staticHandler = StaticHandler.create("webroot")
                            .setCachingEnabled(true)
                            .setMaxAgeSeconds(86400)
                            .setIndexPage("index.html");
                    router.route("/*").handler(staticHandler);

                    router.route().failureHandler(routingContext -> {
                        Throwable failure = routingContext.failure();
                        if (failure != null) {
                            log.error("路由处理异常:", failure);
                            routingContext.response().setStatusCode(500).end("Internal Server Error");
                        }
                    });
                    // 启动HTTP服务器
                    return vertx.createHttpServer()
                            .requestHandler(router)
                            .listen(PORT);
                })
                .onSuccess(server -> {
                    log.info("HTTP server started on port {}",PORT);
                    startPromise.complete();
                })
                .onFailure(startPromise::fail);

        // 注册关闭钩子
        Neo4jController finalNeo4jController = new Neo4jController(vertx);
        Runtime.getRuntime().addShutdownHook(new Thread(()-> {this.shutdown(finalNeo4jController);}));
    }

    private void shutdown(Neo4jController neo4jController) {
        log.info("Shutting down application...");
        // 关闭 Neo4j 驱动
        neo4jController.close();
        // 关闭 Vert.x
        if (vertx != null) {
            vertx.close();
        }
    }
}
